<?php

namespace app\common\cachemodel\chat\call;

use app\common\cachemodel\AppConfig;
use app\common\cachemodel\chat\hz\HzChatRecommendQuestion;
use app\common\cachemodel\chat\hz\HzHzQuestionText;
use app\common\cachemodel\chat\HzChatUserFreeNum;
use app\common\cachemodel\chat\HzDefaultReplyQuestion;
use app\common\cachemodel\zl7\Zl7AiAnswerNumData;
use app\common\cachemodel\ZlUserVip;
use app\common\lib\AliOss;
use app\common\lib\Natal;
use app\common\lib\Util;
use app\common\model\BaseCache;
use XznsTools\cache\CacheManage;

class HzCallChatRecordDetails extends BaseCache
{
    protected $table = 'wechat_backup_07_18_14_43_00.hz_call_chat_record_details';

    protected $cacheModel = 'chat.call_chat_details';

//    $extend = [
//        'add_recode' => 1, // 添加档案信息
//        'recode_info' => '' , // 档案报告信息
//        'fortune_day' => ['time=>'2023-05-01'] , // 档案日运信息
//        'sentence_option' => '' // 澄清信息
//        'default_answer_id' => '' // 默认回复ID
//        'result' =>'' ,  命中选项 信息
//        'zan' => 0 , 点赞状态  1=>赞 2=>踩
//        'result_type' => 1, 结果类型  0=>命中｜澄清命中   1=>澄清   2=>闲聊   3=>默认回复
//        'sas' => 0,     semantic_answer_scene   语义解析集群分类场景结果 当stream为1，并且回调流式接口才会返回 示例 0=>专业，1=>基础，2=>拒答
//        'sact' => [0,1],     semantic_answer_cls_tools   语义解析集群分类工具结果 当stream为1，并且回调流式接口才会返回 示例 [0,0] 第一个元素为api_bot接口返回的recommend_type值，第2个元素为api_bot接口返回的city_type值
//    ];

    /**
     * 获取 初始化 写入数据
     * @param int $chatId
     * @param $recodeInfo
     * @return array[]
     */
    public function getInitData(int $uid, int $chatId, $recodeInfo)
    {
        if (Util::CheckAppVersion('2.10.4') !== '小')
        {   // 新版本
            $content = "不理解太阳、月亮、上升星座？\r\n不知道星盘的意义和作用？\r\n想了解自己的星盘中包含的秘密？\r\n希望占星能够指引你的生活？\r\n快来向准准提问/聊天吧，准准为你答疑解惑～";
        } else
        {   // 旧版本
            $content = "我可以帮你解读星盘，你可以向我提问，我会根据你的星盘回复你。当然这不是我的全部能力，我还在不断的学习中。";
        }
        $nowTimw = time();
        if ($recodeInfo)
        {   // 有档案
            $rid = (int)$recodeInfo['id'];
            //  档案运势信息
            $fortuneInfo = $this->getChatNatalInfo($recodeInfo);
            $recordData = [
                [
                    'chat_id' => $chatId,
                    'uid' => $uid,
                    'rid' => $rid,
                    'type' => 1,
                    'title' => 'Hi，我是准准，尝试与我对话吧',
                    'content' => $content,
                    'data_type' => 1,
                    'extend' => [],
                    'result_data' => '',
                    'option_id' => '',
                    'pid' => 0,
                    'create_time' => $nowTimw,
                ],
                [
                    'chat_id' => $chatId,
                    'uid' => $uid,
                    'rid' => $rid,
                    'type' => 1,
                    'title' => '',
                    'content' => "下面是你的日月升星座",
                    'data_type' => 3,
                    'extend' => [
                        'recode_info' => $fortuneInfo,
                    ],
                    'result_data' => '',
                    'option_id' => '',
                    'pid' => 0,
                    'create_time' => $nowTimw,
                ],
            ];
        } else
        {   // 没有档案
            $recordData = [
                [
                    'chat_id' => $chatId,
                    'uid' => $uid,
                    'rid' => 0,
                    'type' => 1,    // 1=>系统发送消息   2=>用户发送消息
                    'title' => 'Hi，我是准准，尝试与我对话吧',
                    'content' => "$content\r\n\r\n你还没有档案快来添加档案吧~以便我更好的了解你。",
                    'data_type' => 3,
                    'extend' => [
                        'add_recode' => 1,
                    ],
                    'result_data' => '',
                    'option_id' => '',
                    'pid' => 0,
                    'create_time' => $nowTimw,
                ],
            ];
        }

        return $recordData;
    }

    /**
     * 初始化 数据写入
     * @return array
     */
    public function insertInitData(int $chatId, array $insertData)
    {
        try
        {
            $resData = [];
            foreach ($insertData as $insertItem)
            {
                $insertItem['extend'] = json_encode($insertItem['extend'], JSON_UNESCAPED_UNICODE);
                $id = $this->insertGetId($insertItem);
                $insertItem['id'] = (int)$id;

                $insertItem['extend'] = json_decode($insertItem['extend'], true);
                $resData[] = $insertItem;
            }
            // 删除列表缓存
            CacheManage::getInstance()->setCacheConfig($this->cacheModel, $chatId)->rmCache('list');
        }
        catch (\Exception $e)
        {
            \think\Log::write(__CLASS__ . ' => ' . __FUNCTION__ . '()异常：' . $e->getMessage() . '失败信息：' . $e->getFile() . ':' . $e->getLine(), 'error', true);
            $resData = [];
        }

        return $resData;
    }

    public function addRecodeInsertData(int $uid, int $chatId, array $recodeInfo)
    {
        $rid = (int)$recodeInfo['id'];
        //  档案运势信息
        $fortuneInfo = $this->getChatNatalInfo($recodeInfo);
        $insertData = [
            [
                'chat_id' => $chatId,
                'uid' => $uid,
                'rid' => $rid,
                'type' => 1,
                'title' => '档案添加成功',
                'content' => "下面是你的日月升星座",
                'data_type' => 3,
                'extend' => [
                    'recode_info' => $fortuneInfo,
                ],
                'result_data' => '',
                'option_id' => '',
                'pid' => 0,
                'create_time' => time(),
            ],
        ];
        // 写入信息
        $this->SaveData($chatId, $insertData);
    }

    /**
     * 对话写入数据
     */
    public function SaveData(int $chatId, array $datas)
    {
        try
        {
            $resData = [];
            $pid = 0;
            foreach ($datas as $dataItem)
            {
                if ($pid && $dataItem['type'] === 1)    //  1=>APP消息 2=>用户发送消息
                {   // 系统发消息
                    $dataItem['pid'] = $pid;
                }
                $dataItem['extend'] = json_encode($dataItem['extend'], JSON_UNESCAPED_UNICODE);
                $dataItem['result_data'] = $dataItem['result_data'] ? json_encode($dataItem['result_data'], JSON_UNESCAPED_UNICODE) : '';
                $id = $this->insertGetId($dataItem);
                $dataItem['id'] = (int)$id;
                if ($dataItem['type'] === 2)    //  1=>APP消息 2=>用户发送消息
                {
                    $pid = $dataItem['id'];
                }
                $dataItem['extend'] = json_decode($dataItem['extend'], true);
                $dataItem['result_data'] = $dataItem['result_data'] ? json_decode($dataItem['result_data'], true) : [];
                // list ID添加
                $this->listDataAdd($chatId, [$dataItem['id'] => $dataItem['id']]);
                $resData[] = $dataItem;
            }
        }
        catch (\Exception $e)
        {
            \think\Log::write(__CLASS__ . ' => ' . __FUNCTION__ . '()异常：' . $e->getMessage() . '失败信息：' . $e->getFile() . ':' . $e->getLine(), 'error', true);
            return [];
        }

        return $resData;
    }

    /**
     * @param int $chatDetailId
     * @param $data
     * @return bool
     */
    public function UpdateData(int $chatDetailId, $data)
    {
        try
        {
            $data['update_time'] = time();
            $this->where(['id' => $chatDetailId])->update($data);

            CacheManage::getInstance()->setCacheConfig($this->cacheModel, $chatDetailId)->rmCache();

            return true;
        }
        catch (\Exception $e)
        {
            \think\Log::write(__CLASS__ . ' => ' . __FUNCTION__ . '()异常：' . $e->getMessage() . '失败信息：' . $e->getFile() . ':' . $e->getLine(), 'error', true);
            return false;
        }
    }

    /**
     * 获取列表数据
     * @param int $chatId
     * @param int $limit
     * @param int $maxId
     * @return array
     * @throws \Exception
     */
    public function getPageDatas(int $chatId, int $limit, int $maxId = 0)
    {
        $resData = CacheManage::getInstance()
            ->setCacheConfig($this->cacheModel, $chatId)
            ->setPage(-1)
            ->setSort('desc')
            ->getListPageDataIds(function ($isCache = true, $sortType = 'desc') use ($chatId)
            {
                try
                {
                    $data = $this->where(['chat_id' => $chatId])->order("id {$sortType}")->column('id');

                    $resData = [];
                    foreach ($data as $id)
                    {
                        $resData[$id] = ['id' => $id];
                    }

                    return $resData;
                }
                catch (\Exception $e)
                {
                    return [];
                }
            }, 'id', 0);
        if (isset($resData['data']))
        {
            arsort($resData['data']);
            $allIds = array_keys($resData['data']);
        }
        $ids = [];
        $surplusNum = 0;
        foreach ($allIds as $idItem)
        {
            if ($maxId > 0 && $idItem >= $maxId) continue;

            if (count($ids) >= $limit)
            {
                $surplusNum++;
            } else
            {
                $ids[] = $idItem;
            }
        }
        $dataList = $this->batchGetInfoByIds($ids);
        asort($ids);

        $resDataList = [];
        foreach ($ids as $idItem)
        {
            if (isset($dataList[$idItem]))
            {
                $resDataList[] = $dataList[$idItem];
            }
        }

        $resData = [
            'total' => count($allIds),
            'surplus_num' => $surplusNum,
            'data' => $resDataList,
        ];

        return $resData;
    }


    /**
     * 数据 返回样式重组
     * @param array $dataList
     * @param bool $isShowZan
     * @return array
     * @throws \Exception
     */
    public function dataListResert(array $dataList)
    {
        $resData = [];
        $lastTime = 0;
        $now0Time = strtotime(date('Y-m-d')); // 今日0点时间
        foreach ($dataList as $k => $dataItem)
        {
            if ($dataItem['type'] === 3)
            {   // 推荐问题
                $resData[] = $dataItem;
                continue;
            }
            if (isset($dataItem['extend']['answer_violation']) && $dataItem['extend']['answer_violation'])
            {   // 跳过
                continue;
            }
            $createTime = '';
            if ($dataItem['create_time'] - $lastTime > 300)
            {
                $createTime = $this->timeConvert($dataItem['create_time'], $now0Time);
            }
            $audioUrl = $dataItem['url'] ? AliOss::getInstance()->getAuth($dataItem['url']) : '';
            if ($audioUrl)
            {
                $audioUrl = str_replace('http://zhunle.oss-cn-beijing.aliyuncs.com', 'https://oss.goddessxzns.com', $audioUrl);
            }
            $data = [
                'chat_id' => $dataItem['id'],
                'type' => $dataItem['type'],
                'content' => $dataItem['content'],
                'create_time' => $createTime,
                'audio_url' => $audioUrl,
                'audio_duration' => $dataItem['extend']['duration'] ?? 0,  // 音频时长
                'dice_info' => null,
            ];

            switch ($dataItem['data_type'])
            {
                case 2: // 结果信息
                    $data['content'] = $dataItem['result_data'] ? $this->getChatResultDataText($dataItem['result_data']) : '';
                    break;
                case 3: // 扩展信息
                    if (isset($dataItem['extend']['add_recode']))
                    {   // 添加 档案信息
                        $data['add_recode'] = $this->getChatAddRecodeData();
                    }
                    if (isset($dataItem['extend']['recode_info']))
                    {   // 档案 报告信息
                        $data['recode_info'] = $this->getChatRecodeInfoData($dataItem['extend']['recode_info']);
                    }
                    if (isset($dataItem['extend']['fortune_day']))
                    {
                        $data['fortune_info'] = $this->getChatFortuneDayInfoData($dataItem['rid'], $dataItem['extend']['fortune_day']['time']);
                    }
                    if (isset($dataItem['extend']['sentence_option']))
                    {
                        $data['option_info'] = $this->getChatOptionInfoData($dataItem['extend']['sentence_option'], $dataItem['option_id'], isset($dataList[$k + 1]));
                    }
                    if (isset($dataItem['extend']['default_answer_id']))
                    {
                        $data['content'] = $this->getChatDefaultAnswerDataText($dataItem['extend']['default_answer_id']);
                    }
                    if (isset($dataItem['extend']['recommend_synastry']))
                    {
                        $data['recommend_synastry'] = $this->getRecommendSynastryInfo($dataItem['extend']['recommend_synastry']);
                        unset($dataItem['extend']['recommend_good']);
                    }
                    if (isset($dataItem['extend']['recode_choose']))
                    {
                        $data['recode_choose'] = $this->getRecodeChooseInfo($dataItem['extend']['recode_choose']);
                        unset($dataItem['extend']['recommend_good']);
                    }
                    break;
                default:
            }

            if (isset($dataItem['extend']['synastry_result']))
            {
                $data['synastry_result'] = $this->getSynastryResultInfo($dataItem['extend']['synastry_result']);
            }
            if (isset($dataItem['extend']['dice_info']))
            {   // 骰子信息
                $diceInfo = $dataItem['extend']['dice_info'];
                $data['content'] = $diceInfo['answer_content'] ?? '';
                $data['dice_info'] = [
                    'planet' => $diceInfo['planet'],
                    'sign' => $diceInfo['sign'],
                    'house' => $diceInfo['house'],
                ];
            }
            if (isset($dataItem['extend']['is_valid'], $dataItem['extend']['stream']) && $dataItem['extend']['is_valid'] == 1 && $dataItem['extend']['stream'] == 1)
            {
                $data['is_stream_reload'] = 1;
                if (!isset($dataItem['extend']['dice_info']))
                {   // 不是骰子信息
                    $data['content'] = '生成失败';
                }
            } else
            {
                $data['is_stream_reload'] = 0;
            }
            // 更新最后发送时间
            $lastTime = $dataItem['create_time'];
            $resData[] = $data;
        }

        return $resData;
    }

    /**
     * 时间转换
     * @param int $time 待转换的时间
     * @param int $now0Time 今日零点时间
     * @return string
     */
    public function timeConvert(int $time, int $now0Time)
    {
        $t = $now0Time - $time;
        if ($t <= 0)
        {
            $timeStr = date('H:i', $time);
        } elseif ($t <= 86400)
        {
            $timeStr = date('昨日 H:i', $time);
        } else
        {
            $timeStr = date('m-d H:i', $time);
        }

        return $timeStr;
    }

    /**
     * @param array $ids
     * @param array|null $type
     * @param string $sortType
     * @return array
     */
    public function getInfoByIdsInData($ids, $type, $sortType)
    {
        try
        {
            // 获取未删除 的数据
            $data = $this
                ->where(['id' => ['in', $ids]])
                ->column('id,uid,chat_id,rid,type,title,content,url,data_type,extend,result_data,option_id,pid,num_type,create_time,update_time', 'id');
        }
        catch (\Exception $e)
        {
            $data = [];
        }

        return $data;
    }

    public function batchGetInfoByIds($cids, $field = [])
    {
        $resData = parent::batchGetInfoByIds($cids, $field);

        return $this->dataInit($resData);
    }

    /**
     * 数据初始化
     * @param array $data
     * @return array
     */
    public function dataInit(array $data)
    {
        foreach ($data as $index => $itemData)
        {
            $data[$index] = arrayKeyData2int($itemData, ['id', 'uid', 'chat_id', 'rid', 'type', 'data_type', 'pid', 'num_type', 'create_time', 'update_time']);

            if (isset($itemData['extend']))
            {
                $data[$index]['extend'] = $itemData['extend'] ? json_decode($itemData['extend'], true) : [];
            }

            if (isset($itemData['result_data']))
            {
                $data[$index]['result_data'] = $itemData['result_data'] ? json_decode($itemData['result_data'], true) : [];
            }
        }

        return $data;
    }

    /**
     * 获取添加档案数据
     * @return string[]
     */
    public function getChatAddRecodeData(): array
    {
        return [
            'icon' => 'https://oss-haozhun.goddessxzns.com/app/chat/add_recode.png',
            'btn_name' => '手动添加',
            'target' => 'local',
            'link' => 'add_recode?need_auth=2',
        ];
    }

    /**
     * 获取对话 档案信息
     * @param $extendRecodeInfo
     * @return array
     */
    public function getChatRecodeInfoData($extendRecodeInfo): array
    {
        $forecastList = [];
        if (isset($extendRecodeInfo['feelings'], $extendRecodeInfo['dating'], $extendRecodeInfo['money'], $extendRecodeInfo['carrer'], $extendRecodeInfo['academic']))
        {   // 新版本 数据格式
            $forecastList = [
                [
                    'score' => $extendRecodeInfo['feelings'],
                    'color' => '#FFA7C0',
                    'name' => '恋爱',
                ],
                [
                    'score' => $extendRecodeInfo['dating'],
                    'color' => '#54C0F9',
                    'name' => '婚姻',
                ],
                [
                    'score' => $extendRecodeInfo['money'],
                    'color' => '#F9B932',
                    'name' => '财富',
                ],
                [
                    'score' => $extendRecodeInfo['carrer'],
                    'color' => '#A58DFC',
                    'name' => '事业',
                ],
                [
                    'score' => $extendRecodeInfo['academic'],
                    'color' => '#6895FF',
                    'name' => '学业',
                ],
            ];
            $tip2 = '你可以向我提问了，我现在已经非常了解你了～';
        }

        if (isset($extendRecodeInfo['surface']))
        {
            $surface = "表面：{$extendRecodeInfo['surface']}";
        }

        if (isset($extendRecodeInfo['inherent']))
        {
            $inherent = "实则：{$extendRecodeInfo['inherent']}";
        }

        if (empty($forecastList) && Util::CheckAppVersion('2.10.4') === '小')
        {
            $tip2 = "{$surface} {$inherent}";
        }

        return [
            'sun_name' => '太阳' . $extendRecodeInfo['sun'],
            'moon_name' => '月亮' . $extendRecodeInfo['moon'],
            'asc_name' => '上升' . $extendRecodeInfo['asc'],
            'tip1' => empty($forecastList) ? '准准根据你的星座分析你是：' : '准准给你人生的几大方面做了总体评分：',
            'forecast_list' => $forecastList,
            'tip2' => $tip2 ?? '',
            'surface' => $surface ?? '',
            'inherent' => $inherent ?? '',
        ];
    }

    /**
     * 获取对话 选项信息
     * @return array
     */
    public function getChatOptionInfoData(array $sentenceOptionData, string $optionIds, bool $hasNextData)
    {
        $status = !$optionIds && !$hasNextData ? 1 : 2;

        $optionIdsArr = explode(',', $optionIds);
        $optionList = [];
        foreach ($sentenceOptionData as $sentenceOptionItem)
        {
            $optionList[] = [
                'id' => (int)$sentenceOptionItem['id'],
                'text' => $sentenceOptionItem['standsentence'],
                'selected' => in_array($sentenceOptionItem['id'], $optionIdsArr) ? 1 : 0,
            ];
        }

        return [
            'status' => $status,
            'option_list' => $optionList,
        ];
    }

    /**
     * 获取日运信息
     * @param int $rid
     * @return array
     */
    public function getChatFortuneDayInfoData(int $rid, string $time)
    {
        $map = ['time' => strtotime($time), 'rid' => $rid];
        // 取日运信息
        $data = (new \app\common\cachemodel\FortuneCache())->getDayFortune($map, 3);

        $result = $data['revive_day'];
        $test1 = [];
        $test2 = [];
        $test3 = [];
        foreach ($result as $k => $v)
        {
            $new_icon = explode('/', $v['icon_url']);
            array_splice($new_icon, 7, 0, ['v3']);
            $v['icon_url'] = implode('/', $new_icon);

            if ($v['star_level'] == 3 && substr($v['name'], 0, 6) !== '许愿')
            {
                $test1[] = $v;
            } elseif ($v['star_level'] == 3 && substr($v['name'], 0, 6) == '许愿')
            {
                $test2[] = $v;
            } else
            {
                $test3[] = $v;
            }
            // 团圆之日修改为欢聚之日
            if ($v['star_level'] == 3 && substr($v['name'], 0, 6) !== '欢聚')
            {
                $test1[] = $v;
                $test2 = $test3 = [];
                break;
            }
        }
        $result = array_merge($test1, $test2, $test3);
        $reviveDay = $result[0];

        $list = [];
        foreach ($data['fortune_list'] as $k => $datum)
        {
            $score = (int)$datum['score'];
            $list[] = [
                'name' => $datum['name'],
                'score' => min($score, 100),
                'color' => $datum['color'],
            ];
            if ($k >= 4)
            {
                break;
            }
        }

        return [
            'revive_day' => [
                'name' => $reviveDay['name'],
                'star_level' => $reviveDay['star_level'],
                'icon' => $reviveDay['icon_url'],
            ],
            'list' => $list,
            'luck_adversity' => $data['luck_adversity'],
            'target' => 'local',
            'link' => "day?rid={$rid}&time={$time}",
        ];
    }

    /**
     * 可会话 次数 -n
     * @param int $uid
     * @param array $numData
     * @param int $dec
     * @param bool $usrFreeNum 是否使用免费次数【免费次数+vip免费次数】
     * @return array
     * @throws \Exception
     */
    public function chatQueryEndNumDec(int $uid, array $numData, int $dec = 1, bool $usrFreeNum = true): array
    {
        $numData['res_num'] = $numData['res_num'] - $dec;
        if ($usrFreeNum)
        {   // 可用使用免费次数
            if ($numData['free_num'] > 0)
            {   // 使用免费次数
                $n = $numData['free_num'] >= $dec ? $dec : $numData['free_num'];
                $data = (new HzChatUserFreeNum())->getUserFreeNumData($uid);
                $data['free_num'] = $data['free_num'] + $n;
                $numData['free_num'] = $numData['free_num'] - $n;
                (new HzChatUserFreeNum())->UpdateData($uid, 1, $data, $n);
                $numData['use_type'] = 1;   // 使用类型 1=免费次数 2=>vip次数 3=>购买次数 4=>赠送次数
                $dec = $dec - $n;
                if ($dec <= 0)
                {
                    return $numData;
                }
            }
            if ($numData['vip_free_num_today'] > 0)
            {   // 使用 VIP 免费次数
                $n = $numData['vip_free_num_today'] >= $dec ? $dec : $numData['vip_free_num_today'];
                $data = (new HzChatUserFreeNum())->getUserFreeNumData($uid);
                $data['vip_num'] = $data['vip_num'] + $n;
                $numData['vip_free_num_today'] = $numData['vip_free_num_today'] - $n;
                (new HzChatUserFreeNum())->UpdateData($uid, 2, $data, $n);
                $numData['use_type'] = 2;   // 使用类型 1=免费次数 2=>vip次数 3=>购买次数 4=>赠送次数
                $dec = $dec - $n;
                if ($dec <= 0)
                {
                    return $numData;
                }
            }
        }
        if ($numData['admin_num'] > 0)
        {   // 使用 赠送次数
            $n = $numData['admin_num'] >= $dec ? $dec : $numData['admin_num'];
            $numData['admin_num'] = $numData['admin_num'] - $n;
            (new Zl7AiAnswerNumData())->updateData($uid, ['admin_num' => ['dec', $n], 'use_num' => ['inc', $n], 'update_time' => time()]);
            $numData['use_type'] = 4; // 使用类型 1=免费次数 2=>vip次数 3=>购买次数 4=>赠送次数
            $dec = $dec - $n;
            if ($dec <= 0)
            {
                return $numData;
            }
        }
        // 使用 购买次数
        $numData['pay_num'] = $numData['pay_num'] - $dec;
        (new Zl7AiAnswerNumData())->updateData($uid, ['ai_num' => ['dec', $dec], 'use_num' => ['inc', $dec], 'update_time' => time()]);
        $numData['use_type'] = 3;   // 使用类型 1=免费次数 2=>vip次数 3=>购买次数 4=>赠送次数
        return $numData;
    }

    /**
     * 获取 今日 剩余 会话请求次数
     * @param $uid
     * @return array
     * @throws \Exception
     */
    public function getChatQueryEndNumRes($uid)
    {
        $data = (new HzChatUserFreeNum())->getUserFreeNumData($uid);
        $appConfig = (new AppConfig())->configInfo('chat_config');
        $freeNum = (int)($appConfig['free_num'] ?? 0);
        $vipLevel = (new ZlUserVip())->getUserVipLevel($uid);
        if ($vipLevel > 0)
        {
            if (Util::CheckAppVersion('2.10.5') !== '小')
            {
                $vipFreeNum = (int)($appConfig['vip_free_num_today'] ?? 0);
            } else
            {
                $vipFreeNum = 3;
            }
        } else
        {
            $vipFreeNum = 0;
        }
        $payNumData = (new Zl7AiAnswerNumData())->getUserAiNum($uid);

        $numData = [
            'vip_level' => $vipLevel,
            'free_num' => max($freeNum - $data['free_num'], 0),
            'vip_free_num_today' => max($vipFreeNum - $data['vip_num'], 0),
            'pay_num' => $payNumData['ai_num'], // 购买次数
            'admin_num' => $payNumData['admin_num'],    // 赠送次数
        ];
        // 剩余次数  = 免费次数 + vip免费次数 + 购买次数 + 赠送次数
        $numData['res_num'] = max($numData['free_num'] + $numData['vip_free_num_today'] + $numData['pay_num'] + $numData['admin_num'], 0);

        return $numData;
    }

    /**
     *  当前 AI 是否 已经 压力过大
     * @return bool
     */
    public function getIsFullLoad(): bool
    {
        $redis = CacheManage::getInstance()->redisHandler;
        $redis->select(100);

        $res = $redis->get('is_full_load');
        // redis 还原
        $redis->select(0);
        return $res ? true : false;
    }

    /**
     * 获取 输入框 提示文案
     * @param array $numData
     * @return string
     */
    public function getInputPlaceholder(array $numData): string
    {
        if ($numData['free_num'] > 0)
        {
            return sprintf("可免费提问%d次 快来提问吧～", $numData['free_num']);
        }

        if ($numData['res_num'] > 0)
        {
            return '快来向我提问吧～';
        }

        if ($numData['vip_level'] > 0)
        {
            return '机会用尽 明日再来或购买次数';
        } else
        {
            return '体验机会已用尽 请开通会员或购买';
        }
    }

    public function getChatResultDataText(array $resData)
    {
        $str = '';
        $hzQuestionTextModel = new HzHzQuestionText();
        foreach ($resData as $resDatum)
        {
            $textInfo = $hzQuestionTextModel->getTextById($resDatum);
            $str .= ($textInfo['content'] ?? '') . "\n";
        }
        return rtrim($str, "\n");
    }

    /**
     * 获取默认回复 结果
     * @param int $detaultAnswerId
     * @return string
     * @throws \Exception
     */
    public function getChatDefaultAnswerDataText(int $detaultAnswerId): string
    {
        $textData = (new HzDefaultReplyQuestion())->getTextById($detaultAnswerId);

        return $textData['content'] ?? '';
    }

    /**
     * 获取最近会话 次数
     * @param int $chatId
     * @param int $historyNum
     * @param bool $isStream 是否是流式获取
     * @param int $chatDetailId
     * @return array
     * @throws \Exception
     */
    public function getChatQuestionAnswerHistory(int $chatId, int $historyNum, bool $isStream = false, $chatDetailId = 0): array
    {
        if ($isStream)
        {   // 流式数据 多取两条
            $historyNum += 2;
        }
        $pageData = $this->getPageDatas($chatId, $historyNum, 0);

        $pageData = array_column($pageData['data'], null, 'id');

        $resIds = [];
        $resPageData = [];
        foreach ($pageData as $id => $dataItem)
        {
            if (isset($dataItem['extend']['is_call'], $dataItem['extend']['call_text_type']) && $dataItem['extend']['is_call'] === 1 && in_array($dataItem['extend']['call_text_type'], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], true))
            {
                $resIds = [];
                $resPageData = [];
                continue;
            }
            if ($dataItem['type'] === 1 && ($dataItem['content'] || (isset($dataItem['extend']['result_type']) && in_array($dataItem['extend']['result_type'], [0, 2, 3], true))))
            {   // APP 发送消息
                $pid = $dataItem['pid'];
                $questionChatId = 0;
                do
                {
                    if (!$pid || !isset($pageData[$pid]))
                    {
                        break;
                    }
                    if ($pageData[$pid]['type'] === 1)
                    {   // APP消息
                        $pid = $pageData[$pid]['pid'];
                    } else
                    {   // 用户发送消息
                        $questionChatId = $pageData[$pid]['id'];
                    }
                } while ($questionChatId === 0);
                if ($questionChatId > 0)
                {
                    $resIds[$questionChatId] = $id;
                    // 记录重组数据
                    $resPageData[$id] = $dataItem;
                    $resPageData[$questionChatId] = $pageData[$questionChatId];
                }
            }
        }

        $data = $this->dataListResert($resPageData, false, false);
        $data = array_column($data, null, 'chat_id');
        $resData = [];
        foreach ($resIds as $id => $answerId)
        {
//            $answer = str_replace("\n", '', $data[$answerId]['content']);
            if (empty($data[$answerId]['content']) || ($chatDetailId && $chatDetailId == $answerId))
            {   // 没有内容 则跳过
                continue;
            }
            $resData[] = [
                'question' => $data[$id]['content'],
                'answer' => $data[$answerId]['content'],
            ];
        }

        return $resData;
    }

    public function getChatQuestionAnswerLasttime($chatId)
    {
        // 上一条记录为自己发送的消息，所以此处查询两条记录，倒序，取第二条数据的时间
        $pageData = $this->getPageDatas($chatId, 2, 0);

        $data = array_column($pageData['data'], null);

        $lasttime = '';

        if (!empty($data) && isset($data[0]))
        {
            $lasttime = $data[0]['create_time'];
        }

        return $lasttime;
    }

    /**
     * 追加 推荐问题
     * @param array $dataList
     * @param int $rid
     * @return array
     */
    public function addRecommendQuestionResert(array $dataList, int $rid)
    {
        $resData = [];
        $isAdd = false;
        foreach ($dataList as $k => $dataItem)
        {
            $resData[] = $dataItem;
            if ($k < 2 && !$isAdd && $dataItem['data_type'] === 3)
            {
                $item = [
                    'chat_id' => 0,
                    'type' => 3,
                    'title' => '',
                    'content' => '',
                    'zan' => -1,
                    'create_time' => '',
                    'add_recode' => null,
                    'recode_info' => null,
                    'fortune_info' => null,
                    'option_info' => null,
                    'recommend_info' => null,
                    'dice_info' => null,
                    'recommend_question' => [
                        'title' => '常用问题',
                        'list' => (new HzChatRecommendQuestion())->getRecommendQuestion(1, $rid),
                    ],
                    'is_stream_reload' => 0,
                ];
                $resData[] = $item;
                $isAdd = true;
            }
        }

        return $resData;
    }

    /**
     * 获取 推荐信息
     * @param array $recommendInfo
     * @param int $chatDetailId
     * @param int $rid
     * @return array|null
     * @throws \Exception
     */
    public function getRecommendInfo(array $recommendInfo, int $chatDetailId, int $rid = 0)
    {
        $resData = [
            'tip' => '',
            'btn_name' => '',
            'target' => '',
            'link' => '',
            'icon' => '',
            'color_title' => '',
            'color_bg' => '',
            'city_info' => null,
            'btn_is_show' => 1,
            'title' => '',
        ];

        switch ($recommendInfo['recommend_type'])
        {
            case 1: // 1=>合盘
                $resData['tip'] = '推荐你使用合盘功能，了解你和 TA的关系。';
                $resData['btn_name'] = '双人关系合盘揭秘';
                $resData['target'] = 'local';
                $resData['link'] = 'composite?need_auth=1';
                $resData['icon'] = '/app/chat/synastry_icon.png';
                $resData['color_title'] = '#F16B85';
                $resData['color_bg'] = '#FFF3F6';
                break;
            case 2: // 2=>骰子
                if (isset($recommendInfo['style_type']))
                {
                    $resData['title'] = '问题：' . ($recommendInfo['question'] ?? '');
                    $resData['tip'] = '准准发现这个问题也可以用骰子解答，建议你掷出一个骰子，准准可以根据骰子的结果给你分析。';
                } else
                {
                    $resData['tip'] = '建议你掷出一个骰子，准准可以根据骰子的结果给你分析。';
                }

                if (isset($recommendInfo['btn_is_hidden']))
                {
                    $resData['btn_is_show'] = 0;
                } else
                {
                    $resData['btn_name'] = '投出骰子';
                    $resData['target'] = 'local';
                    $question = urlencode($recommendInfo['question'] ?? '');
                    $resData['link'] = "divination_start?question=$question&chat_id={$chatDetailId}&need_auth=2";
                    $resData['icon'] = '/app/chat/dice_icon.png';
                    $resData['color_title'] = '#9175FC';
                    $resData['color_bg'] = '#F7F5FF';
                }
                break;
            case 3: // 3=>城市排行
                //城市排行类型0=>非城市排行返回 1=>幸运 2=>健康 3=>事业 4=>桃花 5=>财富 6=>游乐 7=>安居 8=>知识 9=>社交
                $cityType = '排行';
                switch ($recommendInfo['city_type'])
                {
                    case 1:
                        $cityType = '幸运';
                        break;
                    case 2:
                        $cityType = '健康';
                        break;
                    case 3:
                        $cityType = '事业';
                        break;
                    case 4:
                        $cityType = '桃花';
                        break;
                    case 5:
                        $cityType = '财富';
                        break;
                    case 6:
                        $cityType = '游乐';
                        break;
                    case 7:
                        $cityType = '安居';
                        break;
                    case 8:
                        $cityType = '知识';
                        break;
                    case 9:
                        $cityType = '社交';
                        break;
                }
                $resData['tip'] = "准准通过城市排行功能，帮你计算了全国对你{$cityType}有加分的城市。";
                $resData['btn_name'] = '查看全部城市排行';
                $resData['target'] = 'local';
                $resData['link'] = "acg_map?rid={$rid}&tab_index1=0&tab_index2={$recommendInfo['city_type']}&need_auth=1";
                $resData['icon'] = '/app/chat/city_icon.png';
                $resData['color_title'] = '#00D0C1';
                $resData['color_bg'] = '#E6FFFD';
                $resData['city_info'] = [
                    'default_img' => '/app/chat/city_sort_img.png',
                    'list' => [],
                ];
                break;
            case 4: // 4=>生时矫正
                $resData['tip'] = "一个准确的出生时间在占星中是非常关键的，建议你马上把自己的出生时间修改为自己准确的出生时间。\r\n准准也推荐你利用过往人生大事件，反推你的具体出生时间:";
                $resData['btn_name'] = '校准生辰';
                $resData['target'] = 'local';
                $resData['link'] = "rectification?rid={$rid}&need_auth=1";
                $resData['icon'] = '/app/chat/rectification_icon.png';
                $resData['color_title'] = '#F8C036';
                $resData['color_bg'] = '#FFFAED';
                break;
            case 5: // 5=>吉日吉时
                $resData['tip'] = '准准推荐你使用吉日吉时功能：';
                $resData['btn_name'] = '吉日吉时';
                $resData['target'] = 'local';
                $resData['link'] = "horoscope_select_time_index?rid={$rid}&need_auth=1";
                $resData['icon'] = '/app/chat/horoscope_good_time_icon.png';
                $resData['color_title'] = '#EE9F12';
                $resData['color_bg'] = '#FFFBF3';
                break;
            case 6: // 5=>推荐 提问的问题
                if (isset($recommendInfo['question_recommand']) && $recommendInfo['question_recommand'])
                {
                    $resData = [
                        'tip' => '准准猜你还想问：',
                        'list' => $recommendInfo['question_recommand'],
                    ];
                } else
                {
                    $resData = null;
                }
                break;
            default:
        }

        return $resData;
    }

    public function getNotLogList()
    {
        return [
            [
                'id' => 1,
                'chat_id' => 0,
                'uid' => 0,
                'rid' => 0,
                'type' => 1,    // 1=>系统发送消息   2=>用户发送消息
                'title' => 'Hi，我是准准，尝试与我对话吧',
                'content' => "我可以帮你解读星盘，你可以向我提问，我会根据你的星盘回复你。当然这不是我的全部能力，我还在不断的学习中。\r\n\r\n你还没有档案快来添加档案吧~以便我更好的了解你。",
                'data_type' => 3,
                'extend' => [
                    'add_recode' => 1,
                ],
                'result_data' => '',
                'option_id' => '',
                'pid' => 0,
                'create_time' => time(),
            ],
        ];
    }

    /**
     * @param array $recodeInfo
     * @return array
     */
    public function getChatNatalInfo(array $recodeInfo)
    {
        if (Util::CheckAppVersion('2.10.4') === '小')
        {   //  获取分数及词条
            $natal = (new Natal())->getScoreAndText($recodeInfo);
            $utilModel = new Util();
            $resData = [
                'feelings' => (int)$natal['love'],
                'dating' => (int)$natal['home'],
                'money' => (int)$natal['money'],
                'carrer' => (int)$natal['work'],
                'academic' => (int)$natal['study'],
                'sun' => $utilModel->recodeAstroMiddlehand($recodeInfo['sun']),
                'moon' => $utilModel->recodeAstroMiddlehand($recodeInfo['moon']),
                'asc' => $utilModel->recodeAstroMiddlehand($recodeInfo['asc']),
            ];
        } else
        {
            $res = (new \app\web\service\AstroCard())->getSurfaceAndInherent($recodeInfo);
            $utilModel = new Util();
            $resData = [
                'sun' => $utilModel->recodeAstroMiddlehand($recodeInfo['sun']),
                'moon' => $utilModel->recodeAstroMiddlehand($recodeInfo['moon']),
                'asc' => $utilModel->recodeAstroMiddlehand($recodeInfo['asc']),
                'surface' => $res['surface'],
                'inherent' => $res['inherent'],
            ];
        }

        return $resData;
    }

    /**
     * 获取 推荐合盘 功能插件
     * @param array $recommendSynastry
     * @return array
     */
    public function getRecommendSynastryInfo(array $recommendSynastry)
    {
        // 1=>单盘 2=>合盘
        $type = $recommendSynastry['type'] ?? 1;
        if ($type === 1)
        {
            $tip = '准准发现你的这个问题如果用合盘会有更好的回复，你可以把TA的档案告诉我，我会更好的解决你的问题。';
        } else
        {
            $isCombiningClear = (int)($recommendSynastry['is_combining_clear'] ?? 0);
            $tipList = [
                // 主档案未对齐
                1 => '准准不确认问题中提到的人是否是您当前选择的两个档案，提醒你注意切换档案，或者规范人称描述。',
                // 副档案未对齐
                2 => "准准不确认问题中提到的人是否和副档案“%s”是同一个人，提醒你注意切换档案，或者规范人称的描述。",
            ];

            $tip = $tipList[$isCombiningClear] ?? '';

            if ($isCombiningClear === 2)
            {
                $tip = sprintf($tip, $recommendSynastry['name2'] ?? '');
            }
        }

        switch ($recommendSynastry['status'])
        {
            case 1:
                if ($type === 1)
                {
                    $status = 1;
                    $btnName = '已完成添加';
                } else
                {
                    $status = 4;
                    $btnName = '已回复';
                }
                break;
            case 2:
                if ($type === 1)
                {
                    $status = 2;
                    $btnName = '未选择合盘';
                } else
                {
                    $status = 4;
                    $btnName = '未回复';
                }
                break;
            default:
                if ($type === 1)
                {
                    $status = 0;
                    $btnName = '暂不合盘 继续解答';
                } else
                {
                    $status = 3;
                    $btnName = '确认为该档案 继续解答';
                }
        }
        return [
            'tip' => $tip,
            'status' => $status,
            'recode_avatar1' => $recommendSynastry['avatar1'] ?? '',
            'recode_avatar2' => $recommendSynastry['avatar2'] ?? '',
            'btn_name' => $btnName,
            'recode_name1' => $recommendSynastry['name1'] ?? '',
            'recode_name2' => $recommendSynastry['name2'] ?? '',
        ];
    }

    /**
     * 获取合盘回复 头部标签
     * @param array $synastryResult
     * @return array
     */
    public function getSynastryResultInfo(array $synastryResult)
    {
        return [
            'icon' => '/app/chat/synastry_icon1.png',
            'title' => '合盘回复',
            'rname1' => $synastryResult['rname1'],
            'rname2' => $synastryResult['rname2'],
        ];
    }

    public function getRecodeChooseInfo(array $recodeChoose)
    {
        // $extend['recode_choose'] = [
        //     'rid' => $ridItem,
        //     'status' => 0,  // 0=>等待用户确认解答 1=>已解答 2=>未解答
        //     'avatar' => $avatar,
        //     'name' => $name,
        //     'is_combining_clear' => $isCombiningClear, // 对齐   1=>主档案未对齐    2=>副档案未对齐 【未对齐时不消耗次数】
        // ];

        $tipList = [
            1 => '准准不确认问题中提到的人是否是您当前选择的两个档案，提醒你注意切换档案，或者规范人称描述。',
            2 => "准准不确认问题中提到的人是否和副档案“%s”是同一个人，提醒你注意切换档案，或者规范人称的描述。",
        ];

        $tip = $tipList[$recodeChoose['is_combining_clear']] ?? '';
        if ($recodeChoose['is_combining_clear'] === 2)
        {
            $tip = sprintf($tip, $recodeChoose['name']);
        }

        switch ($recodeChoose['status'])
        {
            case 1:
                $status = 1;
                $btnName = '已回复';
                break;
            case 2:
                $status = 1;
                $btnName = '未回复';
                break;
            default:
                $status = 0;
                $btnName = '使用该档案 继续解答';
        }

        return [
            'tip' => $tip,
            'status' => $status,
            'recode_avatar' => $recodeChoose['avatar'] ?? '',
            'btn_name' => $btnName,
            'type' => $recodeChoose['is_combining_clear'],
            'recode_name' => $recodeChoose['name'],
        ];
    }
}
